<script setup lang="ts">
import {ref, reactive, nextTick} from "vue";
import type {Page} from "@/api/page/types";
import type {Ingredients, IngredientsSearchParam} from "@/api/ingredients/types";
import {addIngredients, deleteIngredients, getIngredientsList, updateIngredients} from "@/api/ingredients";
import EtoakPager from "@/views/compoment/EtoakPager.vue";
import {UseDict} from '@/util/useDict'
import {ElMessage, ElMessageBox} from "element-plus";
import type {FormRules, UploadUserFile, UploadProps} from "element-plus";
import {useTokenStore} from "@/stores/tokenStore";

const tokenStore = useTokenStore()

const INGREDIENTS = 'ingredients'
const {dict, showDictName} = UseDict(INGREDIENTS)

const base_url = import.meta.env.VITE_APP_BASE_API

/*
  查询
  1. 查询表单绑定的数据
  2. 查询表单 ref 属性
  3. 分页total、ingredientsList
  方法
  listIngredients()
 */
const queryForm = reactive<IngredientsSearchParam>({
  pageNum: 1,
  pageSize: 5,
  name: '',
  type: ''
})

const queryFormRef = ref()
const total = ref(0)
const ingredientsList = ref<Ingredients[]>([])

const listIngredients = () => {
  getIngredientsList(queryForm).then((page: Page<Ingredients>) => {
    total.value = page.total
    ingredientsList.value = page.rows
  }).catch(e => {
    console.log(e)
  })
}

/* 点击搜索 */
const search = () => {
  queryForm.pageNum = 1
  listIngredients()
}

/* 重置 */
const resetQueryForm = () => {
  queryFormRef.value.resetFields()
  search()
}

/* 添加 */
// 对话框的标题
const title = ref('添加食材')
// 是否显示对话框
const ingredientsFormVisible = ref(false)

// 添加表单ref属性
const ingredientsFormRef = ref()
// 添加表单 model 属性
const ingredientsForm = ref<Ingredients>({
  name: '',
  type: '',
  url: '',
  description: ''
})
// 添加表单rules属性
const ingredientsFormRules = ref<FormRules>({
  name: [{required: true, message: '请输入食材名称'}],
  type: [{required: true, message: '请选择食材类型'}],
  url: [{required: true, message: '请上传图片'}],
  description: [{required: true, message: '请输入食材描述'}]
})

// fileList
const fileList = ref<UploadUserFile[]>([])
// 文件限制个数
const fileLimit = ref(1)
const handleSuccess: UploadProps['onSuccess'] = (resp, file, files) => {
  ingredientsForm.value.url = resp.data
  ingredientsFormRef.value.validateField('url')
}

/* 上传前执行 */
const handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {
  const isJPG = file.type == 'image/jpeg'
  const isPNG = file.type == 'image/png'
  const isLt1MB = file.size / 1024 / 1024 < 1
  if (!isJPG && !isPNG) {
    ElMessage.warning('仅支持jpg/png格式')
    return false
  }

  if (!isLt1MB) {
    ElMessage.warning('图片大小不能超过1MB')
    return false
  }

}

/* 当超出上传文件个数限制时执行 */
const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
  ElMessage.warning(`只能上传 ${fileLimit} 张图片`)
}

/* 删除图片时执行 */
const handleRemove: UploadProps['onRemove'] = (file) => {
  ingredientsForm.value.url = ''
  fileList.value = []
  ingredientsFormRef.value.validateField('url')
}

/* 点击添加按钮 */
const handleAdd = () => {
  ingredientsFormVisible.value = true
  title.value = '添加食材'
  nextTick(() => {
    ingredientsForm.value = {
      name: '',
      type: '',
      url: '',
      description: ''
    }
    fileList.value = []
    ingredientsFormRef.value.resetFields()
  })
}

/* 点击添加、修改对话框的确认按钮 */
const confirm = () => {
  ingredientsFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      // 添加
      if (!ingredientsForm.value.id) {
        await addIngredients(ingredientsForm.value)
        queryForm.pageNum = 1
      } else { // 更新
        await updateIngredients(ingredientsForm.value.id, ingredientsForm.value)
      }
      // 关闭对话框
      ingredientsFormVisible.value = false

      // 500毫秒后查询列表
      setTimeout(() => {
        listIngredients()
      }, 500)
    }
  })
}

/* 点击修改 */
const handleUpdate = (row: Ingredients) => {
  ingredientsFormVisible.value = true
  title.value = '编辑食材信息'
  nextTick(() => {
    ingredientsForm.value = {...row}
    fileList.value = [{name: row.url, url: base_url + row.url}]
  })
}

/* 点击删除 */
const handleDelete = (id: number) => {
  ElMessageBox.confirm('确认删除?', '警告',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(async () => {
    try {
      await deleteIngredients(id)
      ElMessage.success('操作成功')
      setTimeout(() => {
        listIngredients()
      }, 500)
    }catch (e) {
      console.log(e)
    }
  }).catch(() => {
    ElMessage.info('取消删除')
  })
}

/* 组件渲染后直接执行的方法 */
listIngredients()

</script>

<template>
  <div class="app-container">
    <!-- 添加、修改表单 -->
    <el-dialog
        v-model="ingredientsFormVisible"
        :title="title"
        width="700">
      <!-- 表单 -->
      <el-form
          ref="ingredientsFormRef"
          :rules="ingredientsFormRules"
          :model="ingredientsForm">
        <el-form-item label="食材名称" prop="name">
          <el-input v-model="ingredientsForm.name" placeholder="请输入食材名称"/>
        </el-form-item>
        <el-form-item label="食材图片" prop="url">
          <el-upload
              :headers="{'Authorization': tokenStore.accessToken}"
              :action="base_url + '/dishes-service/upload/image'"
              v-model:file-list="fileList"
              list-type="picture"
              :on-success="handleSuccess"
              :before-upload="handleBeforeUpload"
              :limit="fileLimit"
              :on-exceed="handleExceed"
              :on-remove="handleRemove">
            <el-button type="primary" plain icon="Plus">点击上传</el-button>
            <template #tip>
              <div class="el-upload__tip">支持jpg/png，不能大于1MB</div>
            </template>
          </el-upload>
        </el-form-item>
        <el-form-item label="食材类型" prop="type">
          <el-radio-group
              v-model="ingredientsForm.type">
            <el-radio
                v-for="item in dict[INGREDIENTS]"
                :key="item.name"
                :label="item.name"
                :value="item.value"/>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="食材描述" prop="description">
          <el-input
              type="textarea"
              v-model="ingredientsForm.description"
              placeholder="请输入食材描述"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="ingredientsFormVisible = false">取消</el-button>
          <el-button type="primary" @click="confirm()">确认</el-button>
        </div>
      </template>
    </el-dialog>

    <!--  查询表单  -->
    <el-form
        ref="queryFormRef"
        :model="queryForm"
        inline>
      <el-form-item label="食材名称" prop="name">
        <el-input v-model="queryForm.name" placeholder="请输入食材名称"/>
      </el-form-item>
      <el-form-item label="食材类型" prop="type">
        <el-select v-model="queryForm.type" style="width: 180px" placeholder="请选择食材类型" clearable>
          <el-option
              v-for="item in dict[INGREDIENTS]"
              :key="item.name"
              :label="item.name"
              :value="item.value"/>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" plain icon="Search" @click="search">搜索</el-button>
        <el-button type="info" plain icon="Refresh" @click="resetQueryForm">重置</el-button>
        <el-button type="success" plain icon="Plus" @click="handleAdd">添加</el-button>
      </el-form-item>
    </el-form>

    <!--  表格  -->
    <el-table
        border
        stripe
        :data="ingredientsList"
        style="width: 100%">
      <el-table-column type="index" label="编号" width="70px" align="center"/>
      <el-table-column label="食材名称" prop="name" align="center"/>
      <el-table-column label="食材类型" prop="type" align="center">
        <template #default="scope">
          <el-tag>{{ showDictName(INGREDIENTS, scope.row.type) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="食材图片" align="center">
        <template #default="scope">
          <el-image
              style="width: 40px; height: 40px"
              :src="base_url + scope.row.url"
              :preview-src-list="[base_url + scope.row.url]"
              :preview-teleported="true"
          />
        </template>
      </el-table-column>
      <el-table-column label="创建时间" prop="createTime" align="center"/>
      <el-table-column label="操作" align="center">
        <template #default="scope">
          <el-button type="primary" plain circle icon="Edit" @click="handleUpdate(scope.row)"/>
          <el-button type="danger" plain circle icon="delete" @click="handleDelete(scope.row.id)"/>
        </template>
      </el-table-column>
    </el-table>

    <!--  分页条  -->
    <etoak-pager
        :page-sizes="[5, 10, 20]"
        :total="total"
        v-model:page-num="queryForm.pageNum"
        v-model:page-size="queryForm.pageSize"
        @get-data="listIngredients"/>
  </div>

</template>

<style scoped>

</style>